////////////////////////////////////////////////////////////////////////////////
//(c) Intelliquip, Inc. 2001
////////////////////////////////////////////////////////////////////////////////
//$Log:
// 31   Version 10.0 (Current View)1.30        8/1/2011 10:36:07 AM   Stephen
//      Kish    IDD#09523:  Adding mobile pump size list page
// 30   Version 10.0 (Current View)1.29        7/28/2011 2:13:46 PM   Jeff
//      Heigl      IDD#09523: mobile app start page with units and size list
//      support
// 29   Version 10.0 (Current View)1.28        7/26/2011 2:30:20 PM   Jeff
//      Heigl      IDD#09523: mobile app display formatting, thumbnails page
//      added
// 28   Version 10.0 (Current View)1.27        7/15/2011 12:02:52 PM  Hai Hoang
//            IDD#1757: added saveAs functionality
// 27   Version 10.0 (Current View)1.26        6/23/2011 2:24:27 PM   Stephen
//      Kish    IDD#09523: Adding pdf and send email pages
// 26   Version 10.0 (Current View)1.25        5/23/2011 11:31:46 AM  Jeff
//      Heigl      IDD#09523: perf curve mobile page
// 25   Version 10.0 (Current View)1.24        5/2/2011 11:50:18 AM   Jeff
//      Heigl      IDD#09523: mobile app infrastructure
// 24   Version 10.0 (Current View)1.23        2/28/2011 9:49:50 AM   Stephen
//      Kish    IDD#09403: Bug fixes for enhanced documents page
// 23   Version 10.0 (Current View)1.22        2/14/2011 5:16:08 PM   Stephen
//      Kish    IDD#09460: Fixing transportLog warnings
// 22   Version 10.0 (Current View)1.21        2/2/2011 12:33:46 PM   Stephen
//      Kish    IDD#09403: Enhanced reports view
// 21   Version 10.0 (Current View)1.20        1/27/2011 4:37:53 PM   Stephen
//      Kish    IDD#7885: Moving navbar and footer to abstract design
// 20   Version 10.0 (Current View)1.19        1/24/2011 3:26:35 PM   Stephen
//      Kish    IDD#7855: Moving pages to the abstract design
// 19   Version 10.0 (Current View)1.18        12/16/2010 9:47:34 AM  Stephen
//      Kish    IDD#7855: Moving pages to Abstract selector page design.
// 18   Version 10.0 (Current View)1.17        12/9/2010 4:48:43 PM   Stephen
//      Kish    IDD#7885: Migrating pages to Abstract Selector Page design
// 17   Version 10.0 (Current View)1.16        12/8/2010 10:23:04 AM  Stephen
//      Kish    IDD#7885: Migrating pages to abstract selector design.
// 16   Version 10.0 (Current View)1.15        12/6/2010 12:26:03 PM  Stephen
//      Kish    IDD#7885: Moving selector pages to Abstract selector page
//      design
// 15   Version 10.0 (Current View)1.14        12/2/2010 9:08:56 AM   Stephen
//      Kish    IDD#7885: Migrating pages to abstract selector design.
// 14   Version 10.0 (Current View)1.13        11/19/2010 5:05:27 PM  Stephen
//      Kish    IDD#8122: Migrated start pages to use the new
//      AbstractSelectorPage design.
// 13   Version 10.0 (Current View)1.12        11/11/2010 11:52:45 AM Stephen
//      Kish    IDD#7885: Migrating selector pages to Abstract design
// 12   Version 10.0 (Current View)1.11        11/9/2010 9:31:15 AM   Stephen
//      Kish    IDD#7885:  Migrating pages to use Abstract Selector design
// 11   Version 10.0 (Current View)1.10        11/4/2010 10:49:02 AM  Stephen
//      Kish    IDD#7885: Modified selector pages to use abstract selector page
//      design.
// 10   Version 10.0 (Current View)1.9         11/13/2009 10:16:34 AM Jeff
//      Heigl      IDD#8193: reject reasons page cleanup
// 9    Version 10.0 (Current View)1.8         10/15/2009 9:38:05 AM  Jeff
//      Heigl      IDD#8193: compressor start page focus on link
// 8    Version 10.0 (Current View)1.7         10/14/2009 3:10:26 PM  Jeff
//      Heigl      IDD#8193: infrastructure for gas constituents popup page
// 7    Version 10.0 (Current View)1.6         10/2/2009 2:52:36 PM   Jeff
//      Heigl      IDD#8179: compressor size list page xml
// 6    Version 10.0 (Current View)1.5         9/23/2009 5:03:24 PM   Jeff
//      Heigl      IDD#8162: transport log timings added, curve chartable and
//      director cache implemented
// 5    Version 10.0 (Current View)1.4         7/23/2009 9:28:28 AM   Jeff
//      Heigl      IDD#8031: compressor datasheet page, code cleanup
// 4    Version 10.0 (Current View)1.3         7/21/2009 4:24:47 PM   Jeff
//      Heigl      IDD#7911: setup compressor search page, code cleanup
// 3    Version 10.0 (Current View)1.2         7/20/2009 12:26:34 PM  Jeff
//      Heigl      IDD#7911: page submit refactoring, comment cleanup
// 2    Version 10.0 (Current View)1.1         7/1/2009 2:36:44 PM    Jeff
//      Heigl      IDD#7911: compressor start page
// 1    Version 10.0 (Current View)1.0         6/19/2009 4:57:13 PM   Jeff
//      Heigl      
//$
//$NoKeywords$
////////////////////////////////////////////////////////////////////////////////
package com.intelliquip.hydraulicselection.control.web;

import static com.intelliquip.hydraulicselection.control.web.DisplayController.*;
import static com.intelliquip.hydraulicselection.control.web.DisplayController.isPdPump;

import java.util.Collections;
import java.util.HashMap;
import java.util.Map;

import javax.servlet.http.HttpServletRequest;

import com.intelliquip.core.TransportLogWrapper;
import com.intelliquip.core.servlet.SavePDFServlet;
import com.intelliquip.hydraulicselection.xml.AbstractSelectorPage;
import com.intelliquip.hydraulicselection.xml.AdditionalDataPage;
import com.intelliquip.hydraulicselection.xml.AdvancedSortPage;
import com.intelliquip.hydraulicselection.xml.Api610Page;
import com.intelliquip.hydraulicselection.xml.CFactorPage;
import com.intelliquip.hydraulicselection.xml.CompressorCOSPage;
import com.intelliquip.hydraulicselection.xml.CompressorDatasheetPage;
import com.intelliquip.hydraulicselection.xml.CompressorSearchPage;
import com.intelliquip.hydraulicselection.xml.CompressorSizeListPage;
import com.intelliquip.hydraulicselection.xml.CompressorStartPage;
import com.intelliquip.hydraulicselection.xml.ConditionsOfServicePage;
import com.intelliquip.hydraulicselection.xml.CurveCommentPage;
import com.intelliquip.hydraulicselection.xml.DriverRatingPage;
import com.intelliquip.hydraulicselection.xml.FittingSelectionPage;
import com.intelliquip.hydraulicselection.xml.FooterPage;
import com.intelliquip.hydraulicselection.xml.GasConstituentsPage;
import com.intelliquip.hydraulicselection.xml.HeadLossPage;
import com.intelliquip.hydraulicselection.xml.ITOConditionsOfServicePage;
import com.intelliquip.hydraulicselection.xml.ITOPerformanceDatasheetPage;
import com.intelliquip.hydraulicselection.xml.LifeCycleCostPage;
import com.intelliquip.hydraulicselection.xml.LiquidPropertiesPage;
import com.intelliquip.hydraulicselection.xml.MaxWorkingPressurePage;
import com.intelliquip.hydraulicselection.xml.MotorPerformancePage;
import com.intelliquip.hydraulicselection.xml.MultiSpeedCurvesPage;
import com.intelliquip.hydraulicselection.xml.MultipleConditionsDatasheetPage;
import com.intelliquip.hydraulicselection.xml.MultipleConditionsPage;
import com.intelliquip.hydraulicselection.xml.NPSHAvailablePage;
import com.intelliquip.hydraulicselection.xml.NavBarPage;
import com.intelliquip.hydraulicselection.xml.PerformanceCurvePage;
import com.intelliquip.hydraulicselection.xml.PerformanceDatasheetPage;
import com.intelliquip.hydraulicselection.xml.ProductLineOptionsPage;
import com.intelliquip.hydraulicselection.xml.ProductLinesPageUI;
import com.intelliquip.hydraulicselection.xml.PumpSizeListPage;
import com.intelliquip.hydraulicselection.xml.RejectReasonsPage;
import com.intelliquip.hydraulicselection.xml.RoughnessPage;
import com.intelliquip.hydraulicselection.xml.SaveAsPage;
import com.intelliquip.hydraulicselection.xml.SearchResultsPage;
import com.intelliquip.hydraulicselection.xml.SelectorDocumentsPage;
import com.intelliquip.hydraulicselection.xml.SendEmailPage;
import com.intelliquip.hydraulicselection.xml.SpecialFittingPage;
import com.intelliquip.hydraulicselection.xml.StartPage;
import com.intelliquip.hydraulicselection.xml.SystemDataPage;
import com.intelliquip.hydraulicselection.xml.ThumbnailCurvesPage;
/**
 * Contains the pages and its dependencies.
 *
 * To add a new page:
 * <ul>
 * <li>create a new enum entry</li>
 * <li>create all dependencies</li>
 * <li>create entries in {@link ScreenNames} for the ID and URL, and update the urlMap and screenMap</li>
 * </ul
 *
 * @author Jeff Heigl
 */
public enum PageFactory {
	AdditionalData(ScreenNames.DATASHEET_ADDITIONAL_DATA_SCREEN, "additionalData.xsl"){
		@Override
		public AbstractSelectorPage create(HttpServletRequest request, TransportLogWrapper log) {
			return new AdditionalDataPage(request, getPageDetails(request), log);
		}
		@Override
		public void processPageSubmit(NavigationFlags navFlags) {
			navFlags.processAdditionalDataPage();
		}
	},
	NewAdditionalData(ScreenNames.DATASHEET_ADDITIONAL_DATA_SCREEN, "additionalData.xsl"){
		@Override
		public AbstractSelectorPage create(HttpServletRequest request, TransportLogWrapper log) {
			return new AdditionalDataPage(request, getPageDetails(request), log);
		}
		@Override
		public void processPageSubmit(NavigationFlags navFlags) {
			navFlags.processAdditionalDataPage();
		}
	},
	NewAdditionalData2(ScreenNames.DATASHEET_ADDITIONAL_DATA_SCREEN, "additionalData.xsl"){
		@Override
		public AbstractSelectorPage create(HttpServletRequest request, TransportLogWrapper log) {
			return new AdditionalDataPage(request, getPageDetails(request), log);
		}
		@Override
		public void processPageSubmit(NavigationFlags navFlags) {
			navFlags.processAdditionalDataPage();
		}
	},
	AdvancedSort(ScreenNames.ADVANCED_SORT_SCREEN, "advancedSort.xsl"){
		@Override
		public AbstractSelectorPage create(HttpServletRequest request, TransportLogWrapper log) {
			return new AdvancedSortPage(request, getPageDetails(request), log);
		}
		@Override
		public void processPageSubmit(NavigationFlags navFlags) {
			navFlags.processAdvSortPage();
		}
	},
	Api610(ScreenNames.API610_POPUP_SCREEN, "api610.xsl"){
		@Override
		public AbstractSelectorPage create(HttpServletRequest request, TransportLogWrapper log) {
			return new Api610Page(request, getPageDetails(request), log);
		}
		@Override
		public void processPageSubmit(NavigationFlags navFlags) {
			navFlags.processApi610Page();
		}
	},
	CFactor(ScreenNames.C_FACTOR_SCREEN, "cFactor.xsl"){
		@Override
		public AbstractSelectorPage create(HttpServletRequest request, TransportLogWrapper log) {
			return new CFactorPage(request, getPageDetails(request), log);
		}
		@Override
		public void processPageSubmit(NavigationFlags navFlags) {
		}
	},
	CompressorCOS(ScreenNames.COMPRESSOR_COS_SCREEN, "compressorCOS.xsl") {
		@Override
		public AbstractSelectorPage create(HttpServletRequest request, TransportLogWrapper log) {
			return new CompressorCOSPage(request, getPageDetails(request), log);
		}
		@Override
		public void processPageSubmit(NavigationFlags navFlags) {
			navFlags.processCompressorCos();
		}
	},
	CompressorStart(ScreenNames.START_COMPRESSOR_SCREEN, "compressorStartPage.xsl") {
		@Override
		public AbstractSelectorPage create(HttpServletRequest request, TransportLogWrapper log) {
			return new CompressorStartPage(request, getPageDetails(request), log);
		}
		@Override
		public void processPageSubmit(NavigationFlags navFlags) {
			navFlags.processStartPage();
		}
	},
	CompressorSearch(ScreenNames.COMPRESSOR_SEARCH_SCREEN, "compressorSearch.xsl") {
		@Override
		public AbstractSelectorPage create(HttpServletRequest request, TransportLogWrapper log) {
			return new CompressorSearchPage(request, getPageDetails(request), log);
		}
		@Override
		public void processPageSubmit(NavigationFlags navFlags) {
			navFlags.processCompressorSearchPage();
		}
	},
	CompressorDatasheet(ScreenNames.COMPRESSOR_DATASHEET_SCREEN, "compressorDatasheet.xsl") {
		@Override
		public AbstractSelectorPage create(HttpServletRequest request, TransportLogWrapper log) {
			return new CompressorDatasheetPage(request, getPageDetails(request), log);
		}
		@Override
		public void processPageSubmit(NavigationFlags navFlags) {
			navFlags.processCompressorDatasheetPage();
		}
	},
	CompressorSizeList(ScreenNames.COMPRESSOR_SIZELIST_SCREEN, "compressorSizeList.xsl") {
		@Override
		public AbstractSelectorPage create(HttpServletRequest request, TransportLogWrapper log) {
			return new CompressorSizeListPage(request, getPageDetails(request), log);
		}
		@Override
		public void processPageSubmit(NavigationFlags navFlags) {
			navFlags.processCompressorSizeListPage();
		}
	},
	ConditionsOfService(ScreenNames.CONDITIONS_OF_SERVICE_SCREEN, "conditionsOfService.xsl", "conditionsOfService-mobile.xsl") {
		@Override
		public AbstractSelectorPage create(HttpServletRequest request, TransportLogWrapper log) {
			return new ConditionsOfServicePage(request, getPageDetails(request), log);
		}
		@Override
		public void processPageSubmit(NavigationFlags navFlags) {
			navFlags.processCOS();
		}
	},
	CurveComment(ScreenNames.CURVE_COMMENT_SCREEN, "curveComment.xsl") {
		@Override
		public AbstractSelectorPage create(HttpServletRequest request, TransportLogWrapper log) {
			return new CurveCommentPage(request, getPageDetails(request), log);
		}
		@Override
		public void processPageSubmit(NavigationFlags navFlags) {
			navFlags.processCurveCommentPage();
		}
	},
	DriverRating(ScreenNames.DRIVER_RATING_SCREEN, "driverRating.xsl") {
		@Override
		public AbstractSelectorPage create(HttpServletRequest request, TransportLogWrapper log) {
			return new DriverRatingPage(request, getPageDetails(request), log);
		}
		@Override
		public void processPageSubmit(NavigationFlags navFlags) {
			navFlags.processDriverRatingPage();
		}
	},
	FittingSelection(ScreenNames.FITTING_SELECTION_SCREEN, "fittingSelection.xsl") {
		@Override
		public AbstractSelectorPage create(HttpServletRequest request, TransportLogWrapper log) {
			return new FittingSelectionPage(request, getPageDetails(request), log);
		}
		@Override
		public void processPageSubmit(NavigationFlags navFlags) {
			navFlags.processFittingSelectionPage();
		}
	},
	Footer(ScreenNames.FOOTER_SCREEN, "Footer.xsl") {
		@Override
		public AbstractSelectorPage create(HttpServletRequest request, TransportLogWrapper log) {
			return new FooterPage(request, getPageDetails(request), log);
		}
		@Override
		public void processPageSubmit(NavigationFlags navFlags) {
		}
		@Override
		public boolean isTransportLogSupported() {
			return false;
		}
	},
	GasConstituents(ScreenNames.GAS_CONSTITUENTS_SCREEN, "gasConstituents.xsl") {
		@Override
		public AbstractSelectorPage create(HttpServletRequest request, TransportLogWrapper log) {
			return new GasConstituentsPage(request, getPageDetails(request), log);
		}
		@Override
		public void processPageSubmit(NavigationFlags navFlags) {
			navFlags.processGasConstituentsPage();
		}
	},
	HeadLoss(ScreenNames.HEAD_LOSS_SCREEN, "headLoss.xsl") {
		@Override
		public AbstractSelectorPage create(HttpServletRequest request, TransportLogWrapper log) {
			return new HeadLossPage(request, getPageDetails(request), log);
		}
		@Override
		public void processPageSubmit(NavigationFlags navFlags) {
			navFlags.processHeadLossPage();
		}
	},
	ITOCOS(ScreenNames.ITO_CONDITIONS_OF_SERVICE_SCREEN, "itoConditionsOfService.xsl") {
		@Override
		public AbstractSelectorPage create(HttpServletRequest request, TransportLogWrapper log) {
			return new ITOConditionsOfServicePage(request, getPageDetails(request), log);
		}
		@Override
		public void processPageSubmit(NavigationFlags navFlags) {
			navFlags.processITOConditonsOfServicePage();
		}
	},
	ITODatasheet(ScreenNames.DATASHEET_ITO_SCREEN, "itoDatasheet.xsl") {
		@Override
		public AbstractSelectorPage create(HttpServletRequest request, TransportLogWrapper log) {
			return new ITOPerformanceDatasheetPage(request, getPageDetails(request), log);
		}
		@Override
		public void processPageSubmit(NavigationFlags navFlags) {
			navFlags.processITODatasheetPage();
		}
	},
	LifeCycleCost(ScreenNames.LIFE_CYCLE_COST_SCREEN, "lifeCycleCost.xsl") {
		@Override
		public AbstractSelectorPage create(HttpServletRequest request, TransportLogWrapper log) {
			return new LifeCycleCostPage(request, getPageDetails(request), log);
		}
		@Override
		public void processPageSubmit(NavigationFlags navFlags) {
			navFlags.processLifeCycleCost();
		}
	},
	LiquidProperties(ScreenNames.LIQUID_PROPERTIES_SCREEN, "liquidProperties.xsl") {
		@Override
		public AbstractSelectorPage create(HttpServletRequest request, TransportLogWrapper log) {
			return new LiquidPropertiesPage(request, getPageDetails(request), log);
		}
		@Override
		public void processPageSubmit(NavigationFlags navFlags) {
			navFlags.processLiquidPropertiesPage();
		}
	},
	MaxWorkingPressure(ScreenNames.MAX_WORKING_PRESSURE_SCREEN, "maxWorkingPressure.xsl") {
		@Override
		public AbstractSelectorPage create(HttpServletRequest request, TransportLogWrapper log) {
			return new MaxWorkingPressurePage(request, getPageDetails(request), log);
		}
		@Override
		public void processPageSubmit(NavigationFlags navFlags) {
		}
	},
	MotorPerformance(ScreenNames.MOTOR_PERFORMANCE_SCREEN, "motorPerformance.xsl") {
		@Override
		public AbstractSelectorPage create(HttpServletRequest request, TransportLogWrapper log) {
			return new MotorPerformancePage(request, getPageDetails(request), log);
		}
		@Override
		public void processPageSubmit(NavigationFlags navFlags) {
			navFlags.processMotorPerformanceDatasheetPage();
		}
	},
	MultipleConditions(ScreenNames.MULTIPLE_CONDITIONS_SCREEN, "multipleConditions.xsl") {
		@Override
		public AbstractSelectorPage create(HttpServletRequest request, TransportLogWrapper log) {
			return new MultipleConditionsPage(request, getPageDetails(request), log);
		}
		@Override
		public void processPageSubmit(NavigationFlags navFlags) {
			navFlags.processMultipleConditionsCOS();
		}
	},
	MultipleConditionsDatasheet(ScreenNames.MULTIPLE_CONDITIONS_DATASHEET_SCREEN, "multipleConditionsDatasheet.xsl") {
		@Override
		public AbstractSelectorPage create(HttpServletRequest request, TransportLogWrapper log) {
			return new MultipleConditionsDatasheetPage(request, getPageDetails(request), log);
		}
		@Override
		public void processPageSubmit(NavigationFlags navFlags) {
			navFlags.processMultipleConditionsDatasheet();
		}
	},
	MultiSpeedCurves(ScreenNames.MULTI_SPEED_CURVES_SCREEN, "multiSpeedCurves.xsl") {
		@Override
		public AbstractSelectorPage create(HttpServletRequest request, TransportLogWrapper log) {
			return new MultiSpeedCurvesPage(request, getPageDetails(request), log);
		}
		@Override
		public void processPageSubmit(NavigationFlags navFlags) {
			navFlags.processMultiSpeedCurves();
		}
	},
	NavBar(ScreenNames.NAVBAR_SCREEN, "NavBar.xsl") {
		@Override
		public AbstractSelectorPage create(HttpServletRequest request, TransportLogWrapper log) {
			return new NavBarPage(request, getPageDetails(request), log);
		}
		@Override
		public void processPageSubmit(NavigationFlags navFlags) {
		}
		@Override
		public boolean isTransportLogSupported() {
			return false;
		}
	},
	NPSHAvailable(ScreenNames.NPSH_AVAILABLE_SCREEN, "npshAvailable.xsl") {
		@Override
		public AbstractSelectorPage create(HttpServletRequest request, TransportLogWrapper log) {
			return new NPSHAvailablePage(request, getPageDetails(request), log);
		}
		@Override
		public void processPageSubmit(NavigationFlags navFlags) {
			navFlags.processNPSHAvailablePage();
		}
	},
	PerformanceCurve(ScreenNames.PERFORMANCE_CURVE_SCREEN, "performanceCurve.xsl", "performanceCurve-mobile.xsl") {
		@Override
		public AbstractSelectorPage create(HttpServletRequest request, TransportLogWrapper log) {
			return new PerformanceCurvePage(request, getPageDetails(request), log);
		}
		@Override
		public void processPageSubmit(NavigationFlags navFlags) {
			navFlags.processPerformanceCurve();
		}
	},
	PerformanceDatasheet(ScreenNames.PERFORMANCE_DATASHEET_SCREEN, null) {
		@Override
		public AbstractSelectorPage create(HttpServletRequest request, TransportLogWrapper log) {
			return new PerformanceDatasheetPage(request, getPageDetails(request), log);
		}
		@Override
		public void processPageSubmit(NavigationFlags navFlags) {
			navFlags.processPerformanceDatasheet();
		}
		@Override
		PageDetails getPageDetails(HttpServletRequest request) {
			if(isMobileDevice(request)) {
				return new PageDetailsImpl(screenId, "perfDatasheet-mobile.xsl");
			}

			if(isPdPump(request)) {
				return new PageDetailsImpl(screenId, "perfDatasheetPD.xsl");
			} else {
				return new PageDetailsImpl(screenId, "perfDatasheet.xsl");
			}
		}

	},
	ProductLines(ScreenNames.PRODUCT_LINES_SCREEN, "productLines.xsl", "productLines-mobile.xsl") {
		@Override
		public AbstractSelectorPage create(HttpServletRequest request, TransportLogWrapper log) {
			return new ProductLinesPageUI(request, getPageDetails(request), log);
		}
		@Override
		public void processPageSubmit(NavigationFlags navFlags) {
			navFlags.processProductLines();
		}
	},
	ProductLineOptions(ScreenNames.PRODUCT_LINE_OPTIONS_SCREEN, "productLineOptions.xsl") {
		@Override
		public AbstractSelectorPage create(HttpServletRequest request, TransportLogWrapper log) {
			return new ProductLineOptionsPage(request, getPageDetails(request), log);
		}
		@Override
		public void processPageSubmit(NavigationFlags navFlags) {
			navFlags.processProductLineOptions();
		}
	},
	PumpSizeList(ScreenNames.PUMP_SIZE_LIST_SCREEN, "pumpSizeList.xsl", "pumpSizeList-mobile-page.xsl") {
		@Override
		public AbstractSelectorPage create(HttpServletRequest request, TransportLogWrapper log) {
			return new PumpSizeListPage(request, getPageDetails(request), log);
		}
		@Override
		public void processPageSubmit(NavigationFlags navFlags) {
			navFlags.processPumpSizeList();
		}
	},
	PumpStartPage(ScreenNames.START_PAGE_SCREEN, "startPage.xsl", "startPage-mobile.xsl") {
		@Override
		public AbstractSelectorPage create(HttpServletRequest request, TransportLogWrapper log) {
			return new StartPage(request, getPageDetails(request), log);
		}
		@Override
		public void processPageSubmit(NavigationFlags navFlags) {
			navFlags.processStartPage();
		}
	},
	RejectReasons(ScreenNames.REJECT_REASONS_SCREEN, "rejectReasons.xsl") {
		@Override
		public AbstractSelectorPage create(HttpServletRequest request, TransportLogWrapper log) {
			return new RejectReasonsPage(request, getPageDetails(request), log);
		}
		@Override
		public void processPageSubmit(NavigationFlags navFlags) {
		}
	},
	Roughness(ScreenNames.ROUGHNESS_SCREEN, "roughness.xsl") {
		@Override
		public AbstractSelectorPage create(HttpServletRequest request, TransportLogWrapper log) {
			return new RoughnessPage(request, getPageDetails(request), log);
		}
		@Override
		public void processPageSubmit(NavigationFlags navFlags) {
		}
	},
	SaveAs(ScreenNames.SAVE_AS_SCREEN, "saveAs.xsl"){
		@Override
		public AbstractSelectorPage create(HttpServletRequest request, TransportLogWrapper log) {
			return new SaveAsPage(request, getPageDetails(request), log);
		}

		@Override
		public void processPageSubmit(NavigationFlags navFlags) {
			// nothing to process
		}
	},
	SearchResults(ScreenNames.SEARCH_RESULTS_SCREEN, "searchResults.xsl", "searchResults-mobile.xsl") {
		@Override
		public AbstractSelectorPage create(HttpServletRequest request, TransportLogWrapper log) {
			return new SearchResultsPage(request, getPageDetails(request), log);
		}
		@Override
		public void processPageSubmit(NavigationFlags navFlags) {
			navFlags.processSearchResults();
		}
	},
	SelectorDocuments(ScreenNames.SELECTOR_DOCUMENTS_SCREEN, "selectorDocuments.xsl") {
		@Override
		public AbstractSelectorPage create(HttpServletRequest request, TransportLogWrapper log) {
			return new SelectorDocumentsPage(request, getPageDetails(request), log);
		}
		/**
		 * This will submit to {@link SavePDFServlet}
		 */
		@Override
		public void processPageSubmit(NavigationFlags navFlags) {

		}
	},
	SendEmail(ScreenNames.SEND_EMAIL_SCREEN, "", "send-email.xsl") {
		@Override
		public AbstractSelectorPage create(HttpServletRequest request, TransportLogWrapper log) {
			return new SendEmailPage(request, getPageDetails(request), log);
		}
		/**
		 * This will submit to {@link SavePDFServlet}
		 */
		@Override
		public void processPageSubmit(NavigationFlags navFlags) {
			navFlags.processEmailPage();
		}
	},
	SpecialFitting(ScreenNames.SPECIAL_FITTING_SCREEN , "specialFitting.xsl") {
		@Override
		public AbstractSelectorPage create(HttpServletRequest request, TransportLogWrapper log) {
			return new SpecialFittingPage(request, getPageDetails(request), log);
		}
		@Override
		public void processPageSubmit(NavigationFlags navFlags) {
			navFlags.processSpecialFittingPage();
		}
	},
	SystemData(ScreenNames.SYSTEM_DATA_SCREEN, "systemData.xsl") {
		@Override
		public AbstractSelectorPage create(HttpServletRequest request, TransportLogWrapper log) {
			return new SystemDataPage(request, getPageDetails(request), log);
		}
		@Override
		public void processPageSubmit(NavigationFlags navFlags) {
			navFlags.processSystemData();
		}
	},
	ThumbnailCurves(ScreenNames.THUMBNAIL_CURVES_SCREEN, "thumbnailCurves.xsl", "thumbnailCurves-mobile.xsl") {
		@Override
		public AbstractSelectorPage create(HttpServletRequest request, TransportLogWrapper log) {
			return new ThumbnailCurvesPage(request, getPageDetails(request), log);
		}
		@Override
		public void processPageSubmit(NavigationFlags navFlags) {
			navFlags.processThumbnailCurves();
		}
	}
	;




	private static final Map<Integer, PageFactory> idMap = initIdMap();
	final int screenId;
	private final String xslFileName;
	private final String xslFileName_mobile;

	public abstract AbstractSelectorPage create(HttpServletRequest request, TransportLogWrapper log);
	public abstract void processPageSubmit(NavigationFlags navFlags);

	PageFactory(int screenId, String xslName) {
		this(screenId, xslName, null);
	}

	PageFactory(int screenId, String xslName, String xslName_mobile) {
		this.screenId = screenId;
		this.xslFileName = xslName;
		xslFileName_mobile = xslName_mobile;
	}

	private static Map<Integer, PageFactory> initIdMap() {
		Map<Integer, PageFactory> map = new HashMap<Integer, PageFactory>();
		for(PageFactory value: values()) {
			map.put(value.screenId, value);
		}
		return Collections.unmodifiableMap(map);
	}

	/**
	 * return the {@link PageFactory} or null
	 */
	public static PageFactory getByScreenId(int screenId) {
		return idMap.get(screenId);
	}


	/**
	 * Note: this is overridden in enum types
	 */
	PageDetails getPageDetails(HttpServletRequest request) {
		if(xslFileName_mobile != null && isMobileDevice(request)) {
			return new PageDetailsImpl(screenId, xslFileName_mobile);
		} else {
			return new PageDetailsImpl(screenId, xslFileName);
		}
	}

	public String getName() {
		return name();
	}

	public boolean isTransportLogSupported() {
		return true;
	}

}
